# -*- coding: utf-8 -*-
"""abc ------ 抽象基类"""


"""
class abc.AMCMeta:
    用于定义抽象的基类(ABC)的元类。
    使用该元类以创建抽象基类。抽象基类可以像 mix-in 类一样直接被子类继承。
    你也可以将不相关的具体类（包括内建类）和抽象基类注册为“抽象子类”
     —— 这些类以及它们的子类会被内建函数 issubclass() 识别为对应的抽象基类的子类，
     但是该抽象基类不会出现在其 MRO（Method Resolution Order，方法解析顺序）中，
     抽象基类中实现的方法也不可调用（即使通过 super() 调用也不行）。1
    使用 ABCMeta 作为元类创建的类含有如下方法：
"""

# register（subclass）
#  将"子类"注册为该抽象类的"抽象子类"， 例如：
from abc import ABC, abstractmethod


class MyABC(ABC):
    pass


MyABC.register(tuple)

assert issubclass(tuple, MyABC)
assert isinstance((), MyABC)


# __subclasshook__(subclass)
"""
    必须定义为类方法：
    检查subclass是否 是该抽象基类的子类。也就是说对于那些你希望定义为该抽象类的子类的类，
你不用对每个类调用register()方法了。而是可以直接定义issubclass()的行为。这个类方法是在抽象基类的
__subclasscheck__()方法中调用的。

    该方法必须返回True, False,或是NotImplemented.如果返回True， 
subclass就会被认为是这个抽象类的子类， 如果返回False，无论正常情况是否认为是其子类，统一视为不是。
如果返回NotImplemented，子类检查会按照正常的机制继续执行.
"""


class Foo:
    def __getitem__(self, index):
        ...

    def __len__(self):
        ...

    def get_iterator(self):
        return iter(self)


class MyIterable(ABC):
    @abstractmethod
    def __iter__(self):
        while False:
            yield None

    def get_iterator(self):
        return self.__iter__()

    @classmethod
    def __subclasscheck__(cls, C):
        if cls in MyIterable:
            if any("__iter__" in B.__dict__ for B in C.__mro__):
                return True
        return NotImplemented


MyIterable.register(Foo)



















